package com.fengwenyi.mp3demo.leetcode;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static java.util.stream.Collectors.toList;

/**
 * @author : Caixin
 * @date 2019/7/26 16:33
 */
public class ThreadLeetCode7 {

    // 结果集
//        List<String> list = new ArrayList<>();
//        List<Integer> taskList = Arrays.asList(2, 1, 3, 4, 5, 6, 7, 8, 9, 10);
//        // 全流式处理转换成CompletableFuture[]+组装成一个无返回值CompletableFuture，join等待执行完毕。返回结果whenComplete获取
//        CompletableFuture[] cfs = taskList.stream()
//                .map(integer -> CompletableFuture.supplyAsync(() -> calc(integer))
//                        .thenApply(h->Integer.toString(h))
//                        .whenComplete((s, e) -> {
//                            System.out.println("任务"+s+"完成!result="+s+"，异常 e="+e+","+new Date());
//                            list.add(s);
//                        })
//                ).toArray(CompletableFuture[]::new);
//        // 封装后无返回值，必须自己whenComplete()获取
//        CompletableFuture.allOf(cfs).join();

    private static int calc(Integer i) {
        try {
            if (i == 1) {
                Thread.sleep(3000);//任务1耗时3秒
            } else if (i == 5) {
                Thread.sleep(5000);//任务5耗时5秒
            } else {
                Thread.sleep(1000);//其它任务耗时1秒
            }
            System.out.println("task线程：" + Thread.currentThread().getName()
                    + "任务i=" + i + ",完成！+" + new Date());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return i;
    }




    public static void main(String[] args){
        CompletableFuture<Integer> f1= CompletableFuture.supplyAsync(() -> {
            int t = 4;
            int c=1/0;
            System.out.println(t);
            try {
                TimeUnit.SECONDS.sleep(t);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return t;
        }).exceptionally(x->null);

        CompletableFuture<Integer> f2= CompletableFuture.supplyAsync(() -> {
            int t = 5;
            System.out.println(t);
            try {
                TimeUnit.SECONDS.sleep(t);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return t;
        }).exceptionally(x->null);

        CompletableFuture<Integer> f3= CompletableFuture.supplyAsync(() -> {
            int t = 6;
            int c=1/0;
            System.out.println(t);
            try {
                TimeUnit.SECONDS.sleep(t);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return t;
        }).exceptionally(x->null);

        final List<CompletableFuture<Integer>> futuresList = Arrays.asList(f1, f2, f3);
        CompletableFuture<List<Integer>> result = CompletableFuture.allOf(futuresList.toArray(new CompletableFuture<?>[0]))
                .thenApply(v -> futuresList.stream()
                        .map(CompletableFuture::join)
                        .collect(toList())
                );
        futuresList.forEach(f -> f.whenComplete((t, ex) -> {
            if (ex != null) {
                result.completeExceptionally(ex);
            }
        }));
        System.err.println(result.join());
//     return result;
    }
}
